package main

import (
	"fmt"
	. "go_data_structures_and_algorithms/tool"
)

/*
请你仅使用两个栈实现先入先
出队列。队列应当支持一般队列支持的所有操作（push、pop、peek、empty）：

实现 MyQueue 类：

void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空，返回 true ；否则，返回 false
————————————————
思路:
创建两个栈一个push栈一个pop栈
加入数据的时候直接往push栈压入
取出数据的时候先让push栈的内容取出依次压入pop栈中(这样就行了队列的先进先出的效果)
不过要遵循两条规则，
1. pop栈为空时才能倒，以防打乱原pop栈的出栈顺序
 2. push栈一旦倒，就要倒完，以防打乱原push栈数的顺序
*/
type StackStructureImplementationQueue struct {
	pushShed MyShed[int]
	popShed  MyShed[int]
}

func (q *StackStructureImplementationQueue) Push(v int) {

	q.pushShed.Offer(v)
	q.pushToPop()
	if q.popIsEmpty() {
		fmt.Println("pop栈里面还有数据得先取出来")
	}
}
func (q *StackStructureImplementationQueue) Pop() int {
	q.pushToPop()

	if q.Empty() {
		fmt.Println("已经没有数据了")
		return -1
	}

	return q.popShed.Poll()
}

func (q *StackStructureImplementationQueue) pushToPop() {
	if q.popShed.IsEmpty() {
		for !q.pushShed.IsEmpty() {
			q.popShed.Offer(q.pushShed.Poll())

		}

	}

}
func (q StackStructureImplementationQueue) Empty() bool {
	return q.pushShed.IsEmpty() && q.popShed.IsEmpty()
}

func (q StackStructureImplementationQueue) Peek() int {
	if !q.Empty() {
		return q.popShed.Peek()
	} else {
		fmt.Println("当前没有数据")
		return -1
	}

}
func (q StackStructureImplementationQueue) popIsEmpty() bool {

	return q.popShed.IsEmpty()
}

func main() {
	queue := StackStructureImplementationQueue{
		MyShed[int]{},
		MyShed[int]{},
	}
	queue.Push(1)
	queue.Push(2)
	queue.Push(3)
	queue.Push(4)
	fmt.Println(queue.Pop(), queue.Pop(), queue.Pop())
	queue.Push(5)
	fmt.Println(queue.Pop(), queue.Pop(), queue.Pop())
}
